// Decompiled on 周六 2月 22 19:31:49 CST 2025 with Zomboid Decompiler v0.1.3 using Vineflower.
package zombie.erosion.categories;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import zombie.erosion.ErosionData;
import zombie.erosion.obj.ErosionObj;
import zombie.erosion.obj.ErosionObjOverlay;
import zombie.erosion.obj.ErosionObjOverlaySprites;
import zombie.erosion.obj.ErosionObjSprites;
import zombie.iso.IsoGridSquare;
import zombie.iso.IsoObject;

public final class StreetCracks extends ErosionCategory {
    private ArrayList<ErosionObj> objs = new ArrayList();
    private ArrayList<ErosionObjOverlay> crackObjs = new ArrayList();
    private int[] spawnChance = new int[100];

    @Override
    public boolean replaceExistingObject(
        IsoGridSquare _sq, ErosionData.Square _sqErosionData, ErosionData.Chunk _chunkData, boolean _isExterior, boolean _hasWall
    ) {
        return false;
    }

    @Override
    public boolean validateSpawn(
        IsoGridSquare _sq, ErosionData.Square _sqErosionData, ErosionData.Chunk _chunkData, boolean _isExterior, boolean _hasWall, boolean _isRespawn
    ) {
        int int0 = _sqErosionData.noiseMainInt;
        int int1 = this.spawnChance[int0];
        if (int1 == 0) {
            return false;
        } else if (_sqErosionData.rand(_sq.x, _sq.y, 101) >= int1) {
            return false;
        } else {
            StreetCracks.CategoryData categoryData = (StreetCracks.CategoryData)this.setCatModData(_sqErosionData);
            categoryData.gameObj = _sqErosionData.rand(_sq.x, _sq.y, this.crackObjs.size());
            categoryData.maxStage = int0 > 65 ? 2 : (int0 > 55 ? 1 : 0);
            categoryData.stage = 0;
            categoryData.spawnTime = 50 + (100 - int0);
            if (_sqErosionData.magicNum > 0.5F) {
                categoryData.hasGrass = true;
            }

            return true;
        }
    }

    @Override
    public void update(IsoGridSquare _sq, ErosionData.Square _sqErosionData, ErosionCategory.Data _sqCategoryData, ErosionData.Chunk _chunkData, int _eTick) {
        StreetCracks.CategoryData categoryData = (StreetCracks.CategoryData)_sqCategoryData;
        if (_eTick >= categoryData.spawnTime && !categoryData.doNothing) {
            IsoObject isoObject = _sq.getFloor();
            if (categoryData.gameObj >= 0 && categoryData.gameObj < this.crackObjs.size() && isoObject != null) {
                ErosionObjOverlay erosionObjOverlay = (ErosionObjOverlay)this.crackObjs.get(categoryData.gameObj);
                int int0 = categoryData.maxStage;
                int int1 = (int)Math.floor((double)((float)(_eTick - categoryData.spawnTime) / ((float)erosionObjOverlay.cycleTime / ((float)int0 + 1.0F))));
                if (int1 < categoryData.stage) {
                    int1 = categoryData.stage;
                }

                if (int1 >= erosionObjOverlay.stages) {
                    int1 = erosionObjOverlay.stages - 1;
                }

                if (int1 != categoryData.stage) {
                    int int2 = categoryData.curID;
                    int int3 = erosionObjOverlay.setOverlay(isoObject, int2, int1, 0, 0.0F);
                    if (int3 >= 0) {
                        categoryData.curID = int3;
                    }

                    categoryData.stage = int1;
                } else if (!categoryData.hasGrass && int1 == erosionObjOverlay.stages - 1) {
                    categoryData.doNothing = true;
                }

                if (categoryData.hasGrass) {
                    ErosionObj erosionObj = (ErosionObj)this.objs.get(categoryData.gameObj);
                    if (erosionObj != null) {
                        int int4 = this.currentSeason(_sqErosionData.magicNum, erosionObj);
                        boolean boolean0 = false;
                        boolean boolean1 = false;
                        this.updateObj(_sqErosionData, _sqCategoryData, _sq, erosionObj, boolean0, int1, int4, boolean1);
                    }
                }
            } else {
                categoryData.doNothing = true;
            }
        }
    }

    @Override
    public void init() {
        for (int int0 = 0; int0 < 100; int0++) {
            this.spawnChance[int0] = int0 >= 40 ? (int)this.clerp((float)(int0 - 40) / 60.0F, 0.0F, 60.0F) : 0;
        }

        this.seasonDisp[5].season1 = 5;
        this.seasonDisp[5].season2 = 0;
        this.seasonDisp[5].split = false;
        this.seasonDisp[1].season1 = 1;
        this.seasonDisp[1].season2 = 0;
        this.seasonDisp[1].split = false;
        this.seasonDisp[2].season1 = 2;
        this.seasonDisp[2].season2 = 4;
        this.seasonDisp[2].split = true;
        this.seasonDisp[4].season1 = 4;
        this.seasonDisp[4].season2 = 5;
        this.seasonDisp[4].split = true;
        String string = "d_streetcracks_1_";
        int[] int1 = new int[]{5, 1, 2, 4};

        for (int int2 = 0; int2 <= 7; int2++) {
            ErosionObjOverlaySprites erosionObjOverlaySprites = new ErosionObjOverlaySprites(3, "StreeCracks");
            ErosionObjSprites erosionObjSprites = new ErosionObjSprites(3, "CrackGrass", false, false, false);

            for (int int3 = 0; int3 <= 2; int3++) {
                for (int int4 = 0; int4 <= int1.length; int4++) {
                    int int5 = int4 * 24 + int3 * 8 + int2;
                    if (int4 == 0) {
                        erosionObjOverlaySprites.setSprite(int3, string + int5, 0);
                    } else {
                        erosionObjSprites.setBase(int3, string + int5, int1[int4 - 1]);
                    }
                }
            }

            this.crackObjs.add(new ErosionObjOverlay(erosionObjOverlaySprites, 60, false));
            this.objs.add(new ErosionObj(erosionObjSprites, 60, 0.0F, 0.0F, false));
        }
    }

    @Override
    protected ErosionCategory.Data allocData() {
        return new StreetCracks.CategoryData();
    }

    @Override
    public void getObjectNames(ArrayList<String> list) {
        for (int _int = 0; _int < this.objs.size(); _int++) {
            if (((ErosionObj)this.objs.get(_int)).name != null && !list.contains(((ErosionObj)this.objs.get(_int)).name)) {
                list.add(((ErosionObj)this.objs.get(_int)).name);
            }
        }
    }

    private static final class CategoryData extends ErosionCategory.Data {
        public int gameObj;
        public int maxStage;
        public int spawnTime;
        public int curID = -999999;
        public boolean hasGrass;

        @Override
        public void save(ByteBuffer byteBuffer) {
            super.save(byteBuffer);
            byteBuffer.put((byte)this.gameObj);
            byteBuffer.put((byte)this.maxStage);
            byteBuffer.putShort((short)this.spawnTime);
            byteBuffer.putInt(this.curID);
            byteBuffer.put((byte)(this.hasGrass ? 1 : 0));
        }

        @Override
        public void load(ByteBuffer byteBuffer, int _int) {
            super.load(byteBuffer, _int);
            this.gameObj = byteBuffer.get();
            this.maxStage = byteBuffer.get();
            this.spawnTime = byteBuffer.getShort();
            this.curID = byteBuffer.getInt();
            this.hasGrass = byteBuffer.get() == 1;
        }
    }
}
